#include "hy_stream.h"

NS_HY_BEGIN

schar hy_stream::read_schar()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	schar rv = m_buf[m_cur_pos];
	m_cur_pos += sizeof( schar );
	return rv;
}
uchar hy_stream::read_uchar()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	uchar rv = m_buf[m_cur_pos];
	m_cur_pos += sizeof( uchar );
	return rv;
}
uint16 hy_stream::read_uint16()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	uint16 rv = *(uint16 *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( uint16 );

	if( m_reverse_bytes )
		return reverse_endian_uint16( rv );
	return rv;
}
sint16 hy_stream::read_sint16()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	sint16 rv = *(sint16 *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( sint16 );

	if( m_reverse_bytes )
		return reverse_endian_uint16( rv );
	return rv;
}
uint32 hy_stream::read_uint32()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	uint32 rv = *( uint32 *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( uint32 );
	if( m_reverse_bytes )
		return reverse_endian_sint( rv );
	return rv;
}
sint hy_stream::read_sint()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	sint rv = *( sint *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( sint );
	if( m_reverse_bytes )
		return reverse_endian_sint( rv );
	return rv;
}
float32	hy_stream::read_float32()
{
	if( m_cur_pos > m_max_pos )
	{
		m_error_pos = m_cur_pos;
		return 0;
	}
	float32 rv = *( float32 *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( float32 );
	if( m_reverse_bytes )
		return reverse_endian_float32( rv );
	return rv;
}
uint64 hy_stream::read_uint64()
{
	if( m_cur_pos > m_max_pos )
		return 0;
	uint64 rv = *( uint64 *)(m_buf + m_cur_pos);
	m_cur_pos += sizeof( uint64 );
	if( m_reverse_bytes )
		return reverse_endian_uint64( rv );
	return rv;
}
uint16 hy_stream::read_string( schar *buf, uint /*len*/ )
{
	if( m_cur_pos > m_max_pos )
		return 0;

	sint16 l = read_sint16();
	if( m_reverse_bytes )
		l = reverse_endian_uint16( l );	
		
	for( sint16 i = 0; i < l; ++i )
	{
		buf[i] = read_schar();
		if( m_iswchar )
			read_schar();
	}
	buf[l] = '\0';
	return l;
}
uint16 hy_stream::read_string( std::string &buf )
{
	if( m_cur_pos > m_max_pos )
		return 0;
	buf.clear();
	schar bufss[1024];
	sint16 len = read_sint16();
	if( len > 1024 )
	{
		return -1;
	}
	if( m_reverse_bytes )
		len = reverse_endian_uint16( len );
	
	for( sint16 i = 0; i < len; ++i )
	{
		bufss[i] = read_schar();
		if( m_iswchar )
			read_schar();
	}
	bufss[len] = '\0';
	buf = bufss;
	return len;
}
//////////////////////////////////////////////write//////////////////////////////////////////////
std::string	hy_stream::get_buffer_by_pos( int first_, int end_ )
{
	std::string cur;

	std::stringstream ss;
	if( first_ < 0 || end_ > (int)m_max_pos || first_ > end_ )
		return "";

	for( int i = first_; i <= end_; i++ )
	{
		ss << m_buf[i];
	}
	cur = ss.str();

	return cur;
}
void hy_stream::set_buffer( const char* c, int len )
{
	std::stringstream ss;

	for( int i = 0; i < len; i++ )
	{
		ss << c[i];
	}
	std::string str = ss.str();
	if( str.empty() )
		return;

	m_buf = new schar[str.length()];
	memcpy( m_buf, str.data(), str.length() );
	m_max_pos = (uint64)str.length();
	m_cur_pos = 0;
	m_error_pos = -1;
}
void hy_stream::release_buffer()
{
	if( m_buf )
	{
		delete m_buf;
		m_buf = NULL;
	}
}
bool hy_stream::check_max_pos()
{	
	if( m_is_write_check_max )
	{
		if( m_cur_pos >= m_max_pos )
		{
			return false;
		}
	}
	return true;
}		
bool hy_stream::write_schar( schar c )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( schar ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	m_buf[m_cur_pos] = c;
	m_cur_pos += sizeof( schar );

	return true;
}
bool hy_stream::write_uchar( uchar c )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( uchar ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	m_buf[m_cur_pos] = c;
	m_cur_pos += sizeof( uchar );

	return true;
}
bool hy_stream::write_uint16( uint16 u16 )
{
	if( m_error_pos != -1 )
		return false;

	if( m_cur_pos + sizeof( uint16 ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		u16 = reverse_endian_uint16( u16 );
	}

	*(uint16 *)(m_buf+ m_cur_pos ) = u16;
	m_cur_pos += sizeof( uint16 );

	return true;
}
bool hy_stream::write_sint16( sint16 s16 )
{
	if( m_error_pos != -1 )
		return false;

	if( m_cur_pos + sizeof( sint16 ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		s16 = reverse_endian_uint16( s16 );
	}
	*(sint16 *)(m_buf+ m_cur_pos ) = s16;
	m_cur_pos += sizeof( sint16 );

	return true;
}
bool hy_stream::write_uint32( uint32 u32 )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( uint32 ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		u32 = reverse_endian_sint( u32 );
	}
	*(uint32 *)(m_buf+ m_cur_pos ) = u32;
	m_cur_pos += sizeof( uint32 );

	return true;
}
bool hy_stream::write_sint( sint s32 )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( sint ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		s32 = reverse_endian_sint( s32 );
	}
	*(sint *)(m_buf+ m_cur_pos ) = s32;
	m_cur_pos += sizeof( sint );

	return true;
}
bool hy_stream::write_float32( float32 f32 )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( float32 ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		f32 = reverse_endian_float32( f32 );
	}
	*(float32 *)(m_buf+ m_cur_pos ) = f32;
	m_cur_pos += sizeof( float32 );

	return true;
}
bool hy_stream::write_uint64( uint64 u64 )
{
	if( m_error_pos != -1 )
		return false;
	if( m_cur_pos + sizeof( uint64 ) > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	if( m_reverse_bytes )
	{
		u64 = reverse_endian_uint64( u64 );
	}
	*(uint64 *)(m_buf+ m_cur_pos ) = u64;
	m_cur_pos += sizeof( uint64 );

	return true;
}
bool hy_stream::write_string( const char *c )
{
	if( m_error_pos != -1 )
		return false;

	std::string str = c;

	if( m_cur_pos + str.size() > m_max_pos )
	{
		m_error_pos = m_cur_pos + 1;
		return false;
	}

	for( size_t i = 0; i < str.length(); i++ )
	{
		write_schar( str.at( i ) );
	}
	return true;
}
NS_HY_END